//
//  AirSocket.h
//  AirCpp
//
//  Created by  on 12-9-10.
//  Copyright (c) 2012年 hao peng.

//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
#ifndef AirCpp_AirSocket_h
#define AirCpp_AirSocket_h
#include <stdio.h>

#include "../AirContainer/AirArray.h"
#include "../AirContainer/AirDataStreamBuffer.h"
#include "../AirString/AirString.h"

namespace AirCpp {
#define MAXHOSTNAME 30 //定义域名长度
#define PORTNUM 50000 /* random port number, we need something */

    
    enum CALL_BACK_TYPE_SOCKET {
        CALL_BACK_TYPE_SOCKET_DEFUALT = 0,
        CALL_BACK_TYPE_SOCKET_CONNCETED = 2,
        CALL_BACK_TYPE_SOCKET_SEND = 3,
        CALL_BACK_TYPE_SOCKET_RESEIVED = 4,
        CALL_BACK_TYPE_SOCKET_RESEIVED_CONN_REQUEST = 5,
        CALL_BACK_TYPE_SOCKET_RESEIVED_TIMEOUT = 6,
    };
    
/**
  *	基于BSDSocket的socket类
  */
    template <class CallBack>
    class AirSocket : public AirObject {
        
    public:
        CallBack *callback_target;
        void callback(CALL_BACK_TYPE_SOCKET type, void *value){
            if (NULL != callback_target) {
                switch (type) {
                    case CALL_BACK_TYPE_SOCKET_CONNCETED:
                        callback_target->connected(this, (bool *)value);
                        break;
                    case CALL_BACK_TYPE_SOCKET_RESEIVED:
                        if (NULL == value) {
                            callback_target->received_buffer_finished(this);
                        }else{
                            callback_target->received_buffer(this, (AirString *)value);
                        }
                        break;
                    case CALL_BACK_TYPE_SOCKET_SEND:
                        callback_target->sentdata(this, (bool *)value);
                        break;
                    case CALL_BACK_TYPE_SOCKET_RESEIVED_TIMEOUT:
                        callback_target->recevie_time_out(this);
                    default:
                        break;
                }
            }
        }
        
        long timeout;
//        sockaddr_in *target_addr;
        
        virtual ~AirSocket(){
        }
        
/**
  *	初始化
  *
  *	@return	创建成功返回0 创建失败返回-1
  */
        virtual int init(int domainType, int dataType, int protocol){
            return 0;
        }
        
/**
  *	初始化 方法和上面一样
  *	@param 	domainType 	为创建的套接字指定协议集。 例如：
  *	AF_INET 表示IPv4网络协议
  *	AF_INET6 表示IPv6
  *	AF_UNIX 表示本地套接字（使用一个文件）
  *	@param 	dataType 	type 如下：
  *	SOCK_STREAM （可靠的面向流服务或流套接字）
  *	SOCK_DGRAM （数据报文服务或者数据报文套接字）
  *	SOCK_SEQPACKET （可靠的连续数据包服务）
  *	SOCK_RAW (在网络层之上的原始协议)
  *	@param 	protocol 	protocol 指定实际使用的传输协议。 最常见的就是IPPROTO_TCP、IPPROTO_SCTP、IPPROTO_UDP、IPPROTO_DCCP。这些协议都在<netinet/in.h>中有详细说明。 如果该项为“0”的话，即根据选定的domain和type选择使用缺省协议。
  *	@param 	time_out 	超时时间 默认为0 则设置为系统自己的值
  *
  *	@return	创建成功返回0 创建失败返回-1
  */
        virtual int init(int domainType, int dataType, int protocol, long time_out){
             return 0;
        }
        
/**
  *	关闭连接
  */
         virtual void close_connect()
        {
        }
/**
  *	获取网络的ip地址
  *
  *	@param 	_host 	网络名称、网址
  *
  *	@return	返回ip地址
  */
         virtual AirString * get_ip(const AirString *_host)
        {
            return NULL;
        }
        
        
        
    };
    
    
}
#endif
